package com.woniuxy.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.common.ConstantData;
import com.woniuxy.common.RedisKey;
import com.woniuxy.controller.form.OrderReviewForm;
import com.woniuxy.controller.form.message.OrderLogMessage;
import com.woniuxy.entity.Account;
import com.woniuxy.entity.DietOrder;
import com.woniuxy.dao.DietOrderMapper;
import com.woniuxy.entity.DietOrderFood;
import com.woniuxy.entity.StoreInfo;
import com.woniuxy.exception.orderException.OrderException;
import com.woniuxy.exception.orderException.OrderExceptionCode;
import com.woniuxy.service.AccountService;
import com.woniuxy.service.DietOrderFoodService;
import com.woniuxy.service.DietOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.service.StoreInfoService;
import com.woniuxy.service.dto.AllOrderDto;
import com.woniuxy.service.dto.OrderItemDto;
import com.woniuxy.service.dto.StoreOrderInfoDto;
import com.woniuxy.service.dto.WaiteOrderDto;
import com.woniuxy.util.RedisUtil;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 外卖订单 服务实现类
 * </p>
 *
 * @author zz
 * @since 2023年06月13日
 */
@Service
public class DietOrderServiceImpl extends ServiceImpl<DietOrderMapper, DietOrder> implements DietOrderService {

    @Autowired
    private StoreInfoService storeInfoService;
    @Autowired
    private DietOrderFoodService dietOrderFoodService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private RedisUtil redisUtil;


    //展示当前商家待处理的订单
    @Override
    public StoreOrderInfoDto showStoreOrder(long accountId) throws Exception {
        QueryWrapper<StoreInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accountId",accountId);
        StoreInfo storeInfo = storeInfoService.getOne(queryWrapper);
        Long storeId = storeInfo.getId();
        QueryWrapper<DietOrder> dietOrderQueryWrapper = new QueryWrapper<>();
        dietOrderQueryWrapper.eq("storeId",storeId);
        dietOrderQueryWrapper.eq("state",ConstantData.ORDER_ALREADY_RECEIVE);
//        dietOrderQueryWrapper.ge("orderDate",LocalDate.now());
        dietOrderQueryWrapper.orderByAsc("orderDate");
        List<DietOrder> list = list(dietOrderQueryWrapper);
        if (list==null||list.size()==0){
            StoreOrderInfoDto dto = new StoreOrderInfoDto();
            dto.setNewOrderNum(0);
            return dto;
        }
        DietOrder order = list.get(0);
        StoreOrderInfoDto dto = BeanUtil.toBean(order, StoreOrderInfoDto.class);
        dto.setDispatching(dto.getDispatching().equals("1")?"堂食":"外送");
        //新订单数量
        dto.setNewOrderNum(list.size());
        //今日的新订单数量
        String key = RedisKey.getStoreTurnoverKey(storeId);
        //获取今日的总订单数量以及营业额
        if (redisUtil.exist(key)){
            dto.setAllOrderCount(Integer.valueOf(redisUtil.hsGet(key,"allordercount").toString()));
            dto.setTurnover(BigDecimal.valueOf(Long.parseLong(redisUtil.hsGet(key,"turnover").toString())));
        }else {
            dto.setAllOrderCount(0);
            dto.setTurnover(BigDecimal.valueOf(0));
        }
        QueryWrapper<DietOrderFood> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNum",dto.getOrderNum());
        List<DietOrderFood> list1 = dietOrderFoodService.list(wrapper);
        List<OrderItemDto> itemDtoList = BeanUtil.copyToList(list1, OrderItemDto.class);
        dto.setItems(itemDtoList);
        return dto;
    }

    //商家接单拒单
    @Override
    @Transactional
    public void orderReview(OrderReviewForm form, long accountId) {
        //2：接单 7：拒单
        QueryWrapper<StoreInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accountId",accountId);
        StoreInfo storeInfo = storeInfoService.getOne(queryWrapper);
        Long storeId = storeInfo.getId();
        DietOrder dietOrder = getById(form.getOrderNum());
        if (dietOrder==null || dietOrder.getStoreId().longValue()!=storeId){
            throw new OrderException(OrderExceptionCode.ORDER_NOT_EXIST);
        }
        Integer state = form.getState();
        if (state==2){
            if (dietOrder.getState()!=ConstantData.ORDER_ALREADY_PAY){
                throw new OrderException(5066,"不能接受该订单");
            }
            //接受订单
            dietOrder.setState(ConstantData.ORDER_ALREADY_RECEIVE);
            updateById(dietOrder);
            //创建记录订单日志的消息队列
            OrderLogMessage orderLog = new OrderLogMessage();
            orderLog.setOrderNum(dietOrder.getOrderNum());
            orderLog.setOrderState("已接单");
            orderLog.setOperReason("商家接单");
            orderLog.setOperUser(storeInfo.getUserAccount());
            orderLog.setOperContent("商家已经接单");
            Message<OrderLogMessage> message = MessageBuilder.withPayload(orderLog).build();
            rocketMQTemplate.syncSend("orders_log", message);

        }else {
            if (dietOrder.getState()!=ConstantData.ORDER_ALREADY_PAY){
                throw new OrderException(5066,"不能拒接该订单");
            }
            //拒绝订单
            dietOrder.setState(form.getState());
            dietOrder.setRefuseReason(form.getRefuseReason());
            updateById(dietOrder);
            //创建记录订单日志的消息队列
            OrderLogMessage orderLog = new OrderLogMessage();
            orderLog.setOrderNum(dietOrder.getOrderNum());
            orderLog.setOrderState("已被拒");
            orderLog.setOperReason(form.getRefuseReason());
            orderLog.setOperUser(storeInfo.getUserAccount());
            orderLog.setOperContent("商家已经拒绝该订单");
            Message<OrderLogMessage> message = MessageBuilder.withPayload(orderLog).build();
            rocketMQTemplate.syncSend("orders_log", message);
        }

    }

    @Transactional
    @Override
    public StoreOrderInfoDto orderOut(String orderNum, long accountId) throws Exception {
        QueryWrapper<StoreInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accountId",accountId);
        StoreInfo storeInfo = storeInfoService.getOne(queryWrapper);
        Long storeId = storeInfo.getId();
        DietOrder dietOrder = getById(orderNum);
        if (dietOrder==null || dietOrder.getStoreId().longValue()!=storeId){
            throw new OrderException(OrderExceptionCode.ORDER_NOT_EXIST);
        }
        if(dietOrder.getState()!=ConstantData.ORDER_ALREADY_RECEIVE){
            throw new OrderException(5066,"不能接受该订单");
        }
        dietOrder.setState(ConstantData.ORDER_ALREADY_OUT);
        updateById(dietOrder);
        //修改redis中该商家的今日订单数量以及营业额
        String key = RedisKey.getStoreTurnoverKey(storeId);
        if (redisUtil.exist(key)){
            redisUtil.hsIncryby(key,"allordercount",1);
            //修改营业额
            BigDecimal turnover = BigDecimal.valueOf(Long.parseLong(redisUtil.hsGet(key, "turnover").toString()));
            BigDecimal newTur = turnover.add(dietOrder.getPrice());
            redisUtil.hsPut(key,"turnover",newTur.toString());
        }else {
            //这是当前商家今日的第一单
            LocalDate tomorrow = LocalDate.now().plusDays(1);
            LocalDateTime startOfDay = tomorrow.atStartOfDay();
            long seconds = Duration.between(LocalDateTime.now(), startOfDay).getSeconds();
            redisUtil.hsPut(key,"allordercount",1+"");
            redisUtil.hsPut(key,"turnover",dietOrder.getPrice().toString());
            //设置键的过期时间为一天
            redisUtil.setKeyExpire(key,seconds);
        }

        //创建记录订单日志的消息队列
        OrderLogMessage orderLog = new OrderLogMessage();
        orderLog.setOrderNum(dietOrder.getOrderNum());
        orderLog.setOrderState("已出餐");
        orderLog.setOperReason("商家出餐");
        orderLog.setOperUser(storeInfo.getUserAccount());
        orderLog.setOperContent("商家已出餐");
        Message<OrderLogMessage> message = MessageBuilder.withPayload(orderLog).build();
        rocketMQTemplate.syncSend("orders_log", message);
        QueryWrapper<DietOrder> dietOrderQueryWrapper = new QueryWrapper<>();
        dietOrderQueryWrapper.eq("storeId",storeId);
        dietOrderQueryWrapper.eq("state",ConstantData.ORDER_ALREADY_RECEIVE);
        dietOrderQueryWrapper.ge("orderDate",LocalDate.now());
        dietOrderQueryWrapper.orderByAsc("orderDate");
        //构建返回dto
        StoreOrderInfoDto dto = new StoreOrderInfoDto();
        List<DietOrder> list = list(dietOrderQueryWrapper);
        if (list==null||list.size()==0){
            //获取今日的总订单数量以及营业额
            dto.setAllOrderCount(Integer.valueOf(redisUtil.hsGet(key,"allordercount").toString()));
            dto.setTurnover(BigDecimal.valueOf(Long.parseLong(redisUtil.hsGet(key,"turnover").toString())));
            dto.setNewOrderNum(0);
            return dto;
        }
        DietOrder order = list.get(0);
        dto = BeanUtil.toBean(order, StoreOrderInfoDto.class);
        //获取今日的总订单数量以及营业额
        dto.setAllOrderCount(Integer.valueOf(redisUtil.hsGet(key,"allordercount").toString()));
        dto.setTurnover(BigDecimal.valueOf(Long.parseLong(redisUtil.hsGet(key,"turnover").toString())));
        //新订单数量
        dto.setNewOrderNum(list.size());
        dto.setDispatching(dto.getDispatching().equals("1")?"堂食":"外送");
        QueryWrapper<DietOrderFood> wrapper = new QueryWrapper<>();
        wrapper.eq("orderNum",dto.getOrderNum());
        List<DietOrderFood> list1 = dietOrderFoodService.list(wrapper);
        List<OrderItemDto> itemDtoList = BeanUtil.copyToList(list1, OrderItemDto.class);
        dto.setItems(itemDtoList);
        return dto;
    }

    @Override
    public List<WaiteOrderDto> showWaiteOrder(long accountId) {
        QueryWrapper<StoreInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accountId",accountId);
        StoreInfo storeInfo = storeInfoService.getOne(queryWrapper);
        Long storeId = storeInfo.getId();
        QueryWrapper<DietOrder> dietOrderQueryWrapper = new QueryWrapper<>();
        dietOrderQueryWrapper.eq("storeId",storeId);
        dietOrderQueryWrapper.eq("state",ConstantData.ORDER_ALREADY_PAY);
        dietOrderQueryWrapper.orderByAsc("orderDate");
        List<DietOrder> list = list(dietOrderQueryWrapper);
        if (list==null||list.size()==0){
            return null;
        }
        List<WaiteOrderDto> dtos = BeanUtil.copyToList(list, WaiteOrderDto.class);
        for (WaiteOrderDto dto : dtos) {
            dto.setDispatching(dto.getDispatching().equals("1")?"堂食":"外送");
            QueryWrapper<DietOrderFood> wrapper = new QueryWrapper<>();
            wrapper.eq("orderNum",dto.getOrderNum());
            List<DietOrderFood> list1 = dietOrderFoodService.list(wrapper);
            List<OrderItemDto> itemDtoList = BeanUtil.copyToList(list1, OrderItemDto.class);
            dto.setItems(itemDtoList);
        }
        return dtos;

    }

    @Override
    public List<AllOrderDto> showAllOrder(long accountId) {
        QueryWrapper<StoreInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accountId",accountId);
        StoreInfo storeInfo = storeInfoService.getOne(queryWrapper);
        Long storeId = storeInfo.getId();
        QueryWrapper<DietOrder> dietOrderQueryWrapper = new QueryWrapper<>();
        dietOrderQueryWrapper.eq("storeId",storeId);
        dietOrderQueryWrapper.orderByDesc("orderDate");
        List<DietOrder> list = list(dietOrderQueryWrapper);
        if (list==null||list.size()==0){
            return null;
        }
        List<AllOrderDto> dtos = BeanUtil.copyToList(list, AllOrderDto.class);
        for (AllOrderDto dto : dtos) {
            dto.setDispatching(dto.getDispatching().equals("1")?"堂食":"外送");
            String state = "";
            if (dto.getState().equals("0")){
                state = "待付款";
            }
            if (dto.getState().equals("1")){
                state = "已付款";
            }
            if (dto.getState().equals("2")){
                state = "已接单";
            }
            if (dto.getState().equals("3")){
                state = "已出餐";
            }
            if (dto.getState().equals("4")){
                state = "已完成";
            }
            if (dto.getState().equals("5")){
                state = "已取消";
            }
            if (dto.getState().equals("7")){
                state = "已拒单";
            }
            dto.setState(state);
        }
        return dtos;
    }
}
